import md5 from 'js-md5'
import { Notification } from 'element-ui';
const Config = {
  JiGuang: { appKey: '2e6c0a84091692e8ba197d47', masterSecret: '7467a0cef82eebdb72c13e1f' },
  debug: false
}
const Server = {
  // 生成随机字符串
  randomString(length, chars) {
    var result = '';
    for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
    return result;
  },
  // 通过url获取图片dataURL
  getURLBase64(url) {
    return new Promise((resolve, reject) => {
      if (!url) {
        reject("图片链接为空");
      }
      var xhr = new XMLHttpRequest()
      xhr.open('get', url, true)
      xhr.responseType = 'blob'
      xhr.onload = function () {
        if (this.status === 200) {
          var blob = this.response
          var fileReader = new FileReader()
          fileReader.onloadend = function (e) {
            var result = e.target.result
            resolve(result)
          }
          fileReader.readAsDataURL(blob)
        }
      }
      xhr.onerror = function () {
        reject()
      }
      xhr.send()
    })
  },
  // 图片dataURL转文件
  btof(data, fileName) {
    const dataArr = data.split(",");
    const byteString = atob(dataArr[1]);

    const options = {
      type: "image/jpeg",
      endings: "native"
    };
    const u8Arr = new Uint8Array(byteString.length);
    for (let i = 0; i < byteString.length; i++) {
      u8Arr[i] = byteString.charCodeAt(i);
    }
    return new File([u8Arr], fileName + ".jpg", options);
  }
}
const state = {
  JIM: new JMessage({ debug: Config.debug }),
  password: '123456',
  loginUser: {},
  autoScroll: true,
  conversations: [],                          //会话列表
  asyncMessages: [],                          //离线同步信息
}

const getters = {
  JIM: state => state.JIM,
  loginUser: state => state.loginUser,
  conversations: state => state.conversations,
  asyncMessages: state => state.asyncMessages,
  autoScroll: state => state.autoScroll,
}

const mutations = {
  setJIM(state, d) {
    state.JIM = d;
  },
  saveLoginUser(state, d) {
    state.loginUser = d;
  },
  saveAutoScroll(state, d) {
    state.autoScroll = d;
  },
  addConversations(state, d) {
    console.log('保存会话',d);
    if (state.conversations.findIndex(item => item.key === d.key) === -1) {
      state.conversations.unshift(d);
    }
  },
  clearConversations(state) {
    state.conversations = [];
  },
  setAsyncMessages(state, d) {
    state.asyncMessages = d;
  },
  // 接收到消息处理
  addUnRead(state, { index, msg }) {
    let conversation = state.conversations[index];
    state.autoScroll = true;
    state.conversations[index].unread_msg_count = state.JIM.getUnreadMsgCnt(conversation);
    let convIndex = -1;
    if (msg.msg_type === 3) {    //单聊
      convIndex = state.asyncMessages.findIndex(conv => conv.from_username === msg.from_username);
      if (convIndex === -1) {
        const asyncMsg = {
          from_appkey: msg.from_appkey,
          from_username: msg.from_username,
          key: msg.key,
          msg_type: msg.msg_type,
          msgs: [msg],
          receipt_msgs: [],
          unread_msg_count: state.JIM.getUnreadMsgCnt(conversation)
        }
        state.asyncMessages.push(asyncMsg);
      }
    } else if (msg.msg_type === 4) {     //群聊
      convIndex = state.asyncMessages.findIndex(conv => conv.from_gid === `${msg.from_gid}`);
      if (convIndex === -1) {
        const asyncMsg = {
          from_gid: msg.from_gid.toString(),
          key: msg.key,
          msg_type: msg.msg_type,
          msgs: [msg],
          receipt_msgs: [],
          unread_msg_count: state.JIM.getUnreadMsgCnt(conversation)
        }
        state.asyncMessages.push(asyncMsg);
      }
    }
    if (convIndex !== -1) {
      state.asyncMessages[convIndex].msgs.push(msg);
    }
  },
  // 发送消息后处理
  addReadMsg(state, { index, msg }) {
    msg.ctime_ms = new Date().getTime();
    let conversation = state.conversations[index];
    state.autoScroll = true;
    conversation.unread_msg_count = 0;
    if (index !== 0) {
      state.conversations.splice(index, 1);
      state.conversations.unshift(conversation);
    }
    let asyncIndex = -1;
    if (conversation.type === 3) {
      asyncIndex = state.asyncMessages.findIndex(item => item.msg_type === 3 && item.from_username === msg.target_id);
      if (asyncIndex === -1) {
        state.asyncMessages.push({
          from_appkey: msg.appkey,
          from_username: msg.target_id,
          key: msg.key,
          msg_type: 3,
          msgs: [msg],
          receipt_msgs: [],
          unread_msg_count: 0
        })
      }
    } else if (conversation.type === 4) {
      asyncIndex = state.asyncMessages.findIndex(item => item.msg_type === 4 && item.from_gid === msg.target_gid);
      if (asyncIndex === -1) {
        state.asyncMessages.push({
          from_gid: msg.target_gid,
          key: msg.key,
          msg_type: 4,
          msgs: [msg],
          receipt_msgs: [],
          unread_msg_count: 0
        })
      }
    }
    if (asyncIndex !== -1) {
      state.asyncMessages[asyncIndex].msgs.push(msg);
    }
  }
}


const actions = {
  initJmessage({ commit, dispatch, state }) {
    let timestamp = new Date().getTime();                                               //当前时间戳，用于防止重放攻击，精确到毫秒
    let random_str = Server.randomString(36, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'); //20-36 长度的随机字符串, 作为签名加 salt 使用
    let signature = md5(`appkey=${Config.JiGuang.appKey}&timestamp=${timestamp}&random_str=${random_str}&key=${Config.JiGuang.masterSecret}`); //签名，10 分钟后失效（只针对初始化操作，初始化成功则之后的操作跟签名无关）
    return new Promise((resolve, reject) => {
      state.JIM.init({ appkey: Config.JiGuang.appKey, random_str: random_str, timestamp: timestamp, signature: signature, flag: 1 }).onSuccess(data => {
        resolve(data);
      }).onFail(data => {
        Notification.error(data);
        reject(data);
      })
    })
  },
  // 登录IM
  async loginIM({ commit, dispatch, state }, userInfo) {
    console.log('isInit', state.JIM.isInit(), userInfo);
    if (state.JIM && state.JIM.isInit()) {
      if (!state.JIM.isLogin()) {
        console.log('用户信息', { username: userInfo.user_id, password: state.password });
        state.JIM.login({ username: userInfo.user_id, password: state.password }).onSuccess(data => {
          console.log('登录成功,获取会话列表', data);//登录成功,获取会话列表
          dispatch("getUserInfo", userInfo);
          dispatch("getConversation");
          dispatch('onSyncConversation');
          dispatch("onMsgReceive");
        }).onFail(data => {
          Notification.error({ title: '聊天模块登录失败', message: data.message });
          if (data.code === 880103) { //用户不存在，注册
            Notification.error({ title: '正在注册聊天' });
            console.log(1111111111, data);
            dispatch('registerIM', userInfo)
          }
        })
      }
    } else {
      await dispatch('initJmessage').then(res => {
        dispatch('loginIM', userInfo);
      })
    }
  },
  // 退出登录
  logoutIM({ state, commit }) {
    commit('clearConversations');
    commit('saveLoginUser', {});
    state.JIM.loginOut();
  },
  // 注册IM
  registerIM({ commit, dispatch, state }, userInfo) {
    console.log('register', { username: userInfo.user_id, password: state.password, nickname: userInfo.nick_name, media_id: userInfo.head_img });
    state.JIM.register({ username: userInfo.user_id, password: state.password, nickname: userInfo.nick_name, media_id: userInfo.head_img })
      .onSuccess(data => {   //注册成功，登录
        Notification.success({ title: '聊天模块注册成功' });
        dispatch('loginIM', userInfo);
      }).onFail(data => {    //注册失败
        throw Error(data);
        // Notification.error({ title: '聊天模块注册失败', message: data.message });
      })
  },
  // 获取用户信息
  getUserInfo({ commit, dispatch, state }, userInfo) {
    state.JIM.getUserInfo({ username: userInfo.user_id }).onSuccess(data => {
      dispatch("getMedia", data.user_info.avatar).then(res => {
        data.user_info.avatar = res.url;
        commit('saveLoginUser', data.user_info);
      })
      commit('saveLoginUser', data.user_info);
      let distanceTime = new Date().getTime() - new Date(data.user_info.mtime).getTime();
      if (distanceTime > 6 * 60 * 60 * 1000) {                                  //距离上次用户信息修改超过6个小时更新头像
        console.log('userInfo.head_img', userInfo.head_img);
        if (userInfo.head_img) {
          Server.getURLBase64(userInfo.head_img).then(base64 => {
            let formData = new FormData();
            formData.append('avatar', Server.btof(base64, 'avatar'))
            state.JIM.updateSelfAvatar({ 'avatar': formData }).onSuccess(data1 => {
              dispatch('getUserInfo', userInfo);
            }).onFail(data1 => {
              throw Error(data1);
              // Notification.error(data1);
            })
          })
        }
      }
    }).onFail(data => {
      Notification.error({ title: '聊天模块注册失败', message: data.message });
    })
  },
  // 获取会话列表
  getConversation({ commit, dispatch, state }) {
    commit('clearConversations');
    state.JIM.getConversation().onSuccess(data => {
      console.log('会话列表',data);
      data.conversations.forEach(item => {
        if (item.avatar) {
          dispatch('getMedia', item.avatar).then(res => {
            item.avatar = res.url;
            commit('addConversations', item);
          }).catch(e=>{
            commit('addConversations', item);
          })
        } else {
          commit('addConversations', item);
        }
      });
    }).onFail(data => {
      Notification.error({ title: '会话列表获取失败', message: data.message });
    })
  },
  // 离线消息
  onSyncConversation({ commit, dispatch, state }) {
    state.JIM.onSyncConversation(function (data) {
      commit('setAsyncMessages', data);
    })
  },
  // 接收实时聊天消息
  onMsgReceive({ commit, dispatch, state }) {
    state.JIM.onMsgReceive(data => {
      if (data.event === 'msg_sync') {
        data.messages.forEach(item => {
          Notification.success({
            title: (item.content.target_name ? `${item.content.target_name} · ` : '') + item.content.from_name,
            message: item.content.msg_type === 'text' ? item.content.msg_body.text : `[${item.content.msg_type === 'image' ? '图片' : '文件'}]`
          });
          console.log('receipt', item);

          let convIndex = -1;
          if (item.msg_type === 3) {    //单聊
            convIndex = state.conversations.findIndex(conv => conv.username === item.from_username);
          } else if (item.msg_type === 4) {     //群聊
            convIndex = state.conversations.findIndex(conv => conv.gid === `${item.from_gid}`);
          }
          console.log('onMsgReceive', convIndex);

          if (convIndex === -1) {
            if (item.msg_type === 3) {
              commit('addConversations', {
                appkey: item.from_appkey,
                avatar: '',
                key: `${item.key}`,
                mtime: item.ctime_ms,
                name: item.content.from_id,
                nickName: item.content.from_name,
                type: 3,
                unread_msg_count: 1,
                username: item.content.target_id
              })
            } else if (item.msg_type === 4) {
              commit('addConversations', {
                appKey: item.content.from_appkey,
                avatar: '',
                gid: item.content.target_id,
                key: `${item.key}`,
                mtime: item.ctime_ms,
                name: item.content.target_name,
                type: 4,
                unread_msg_count: 1
              })
            }
          }
          commit('addUnRead', { index: convIndex, msg: item });
        })
      }
    })
  },
  // 发送文字消息
  sendMsg({ commit, dispatch, state }, { conversation, message }) {
    let convIndex = state.conversations.findIndex(item => {
      if (conversation.type === 3) {
        return item.username === conversation.username;
      } else if (conversation.type === 4) {
        return item.gid === conversation.gid;
      }
    });
    if (conversation.type === 3) {
      state.JIM.sendSingleMsg({
        target_username: conversation.username,
        content: message,
      }).onSuccess(function (data, msg) {
        dispatch('resetUnreadCount', conversation);
        commit('addReadMsg', { index: convIndex, msg: msg });
      }).onFail(data => {
        Notification.error(data);
      })
    } else if (conversation.type === 4) {
      state.JIM.sendGroupMsg({
        target_gid: conversation.gid,
        content: message,
      }).onSuccess((data, msg) => {
        dispatch('resetUnreadCount', conversation);
        commit('addReadMsg', { index: convIndex, msg: msg });
      }).onFail(data => {
        Notification.error(data);
      })
    }
  },
  // 发送图片
  sendPic({ commit, dispatch, state }, { conversation, url }) {
    let convIndex = state.conversations.findIndex(item => {
      if (conversation.type === 3) {
        return item.username === conversation.username;
      } else if (conversation.type === 4) {
        return item.gid === conversation.gid;
      }
    });
    Server.getURLBase64(url).then(base64 => {
      let formData = new FormData();
      formData.append('avatar', Server.btof(base64, 'avatar'))
      if (conversation.type === 3) {
        state.JIM.sendSinglePic({
          target_username: conversation.username,
          image: formData,
        }).onSuccess((data, msg) => {
          dispatch('resetUnreadCount', conversation)
          commit('addReadMsg', { index: convIndex, msg: msg });
        }).onFail(data => {
          Notification.error(data);
        })
      } else if (conversation.type === 4) {
        state.JIM.sendGroupPic({
          target_gid: conversation.gid,
          image: formData,
        }).onSuccess((data, msg) => {
          dispatch('resetUnreadCount', conversation)
          commit('addReadMsg', { index: convIndex, msg: msg });
        }).onFail(data => {
          Notification.error(data);
        })
      }
    })
  },
  // 获取资源访问路径
  getMedia({ state }, mediaId) {
    return new Promise((resolve, reject) => {
      if (mediaId) {
        state.JIM.getResource({ media_id: mediaId }).onSuccess(res => {
          resolve(res);
        }).onFail(data => {
          reject(data);
          // Notification.error(data);
        })
      }
    });
  },
  // 获取会话用户信息
  getChatUserInfo({ state, dispatch }, username) {
    return new Promise((resolve, reject) => {
      state.JIM.getUserInfo({ username: username }).onSuccess(data => {
        if (data.user_info.avatar) {
          dispatch("getMedia", data.user_info.avatar).then(res => {
            data.user_info.avatar = res.url;
            resolve(data);
          })
        } else {
          resolve(data);
        }
      }).onFail(data => {
        Notification.error(data);
        reject(data);
      })
    })
  },
  // 重置未读数
  resetUnreadCount({ state }, { username, gid }) {
    state.JIM.resetUnreadCount({ username, gid });
  }
}

export default {
  state, getters, mutations, actions
}